package com.client.utils;

import com.client.sm9.gm.sm9.SM9Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@Component
public class MessageUtils {

    public static Date getNowTime() {
        long time = new Date().getTime();
        return new Date(time);
    }

    public static byte[] Hash_SM3(byte[] bytes) {
        return SM9Utils.Hash(bytes);
    }

    public static UUID getuuid() {
        return UUID.randomUUID();
    }

    //认证数据包的hash
    public static byte[] HashOfCertification(Map<String, Object> map) {
        List<byte[]> list = new ArrayList<>();
        if (map.containsKey("id"))
            list.add(((String) map.get("id")).getBytes(StandardCharsets.UTF_8));
        if (map.containsKey("time"))
            list.add(Utils.getByteFromDate((Date) map.get("time")));
        if (map.containsKey("uid"))
            list.add(Utils.getByteFromUUID((UUID) map.get("uid")));
        if (map.containsKey("uuid"))
            list.add(Utils.getByteFromUUID((UUID) map.get("uuid")));
        if (map.containsKey("type"))
            list.add(((String) map.get("type")).getBytes(StandardCharsets.UTF_8));
        if (map.containsKey("port"))
            list.add(Utils.getByteFromInteger((Integer) map.get("port")));
        if (map.containsKey("n"))
            list.add(Utils.getByteFromInteger((Integer) map.get("n")));
        if (map.containsKey("f(n)"))
            list.add(Utils.getByteFromInteger((Integer) map.get("f(n)")));

        byte[] bytes = bytecat(list);

        return Hash_SM3(bytes);
    }

    //密钥交换数据包的hash
    public static byte[] HashOfExchange(Map<String, Object> map, Integer n) {
        List<byte[]> list = new ArrayList<>();
        if (map.containsKey("id"))
            list.add(((String) map.get("id")).getBytes(StandardCharsets.UTF_8));
        if (map.containsKey("time"))
            list.add(Utils.getByteFromDate((Date) map.get("time")));
        if (map.containsKey("uid"))
            list.add(Utils.getByteFromUUID((UUID) map.get("uid")));
        if (map.containsKey("uuid"))
            list.add(Utils.getByteFromUUID((UUID) map.get("uuid")));
        if (map.containsKey("type"))
            list.add(((String) map.get("type")).getBytes(StandardCharsets.UTF_8));
        if (map.containsKey("R"))
            list.add((byte[]) map.get("R"));
        if (map.containsKey("S"))
            list.add((byte[]) map.get("S"));

        list.add(Utils.getByteFromInteger(n));

        byte[] bytes = bytecat(list);

        return Hash_SM3(bytes);
    }

    //正常通信数据包的hash
    public static byte[] HashOfFormal(Map<String, Object> map, byte[] k) {
        List<byte[]> list = new ArrayList<>();
        if (map.containsKey("id"))
            list.add(((String) map.get("id")).getBytes(StandardCharsets.UTF_8));
        if (map.containsKey("time"))
            list.add(Utils.getByteFromDate((Date) map.get("time")));
        if (map.containsKey("uid"))
            list.add(Utils.getByteFromUUID((UUID) map.get("uid")));
        if (map.containsKey("uuid"))
            list.add(Utils.getByteFromUUID((UUID) map.get("uuid")));
        if (map.containsKey("body"))
            list.add((byte[]) map.get("body"));
        list.add(k);
        byte[] bytes = bytecat(list);

        return Hash_SM3(bytes);
    }

    //拼接字节数组
    public static byte[] bytecat(List<byte[]> list) {
        byte[] b = new byte[0];
        for (byte[] bytes : list) {
            b = ByteBuffer.allocate(b.length + bytes.length).put(b).put(bytes).array();
        }
        return b;
    }


}
